package com.feshfans.controller.special;

import com.feshfans.bridge.RoomBridge;
import com.feshfans.controller.RegisteredController;
import com.feshfans.xmpp.client.RoomClient;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.Node;
import javafx.scene.control.Alert;
import javafx.scene.control.Label;
import javafx.scene.control.TextArea;
import javafx.scene.control.TextInputDialog;
import javafx.scene.layout.VBox;
import org.jivesoftware.smack.chat.Chat;
import org.jivesoftware.smack.util.StringUtils;
import org.jivesoftware.smackx.muc.Affiliate;
import org.jivesoftware.smackx.muc.MultiUserChat;
import org.jxmpp.jid.BareJid;
import org.jxmpp.jid.EntityBareJid;
import org.jxmpp.jid.Jid;
import org.jxmpp.jid.impl.JidCreate;
import org.jxmpp.jid.parts.Resourcepart;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.ResourceBundle;

public class RoomController extends RegisteredController<EntityBareJid> implements Initializable {

    private static final Logger Log = LoggerFactory.getLogger(RoomController.class);

    private EntityBareJid roomJid;
    private RoomClient roomClient;
    private MultiUserChat multiUserChat;
    private RoomBridge roomBridge;

    @FXML private TextArea historyTextArea;
    @FXML private TextArea sendTextArea;
    @FXML private VBox memerbersVBox;

    public RoomController(){
        roomClient = RoomClient.getInstance();
        roomBridge = RoomBridge.getInstance();
    }

    @Override
    public void initialize(URL location, ResourceBundle resources) {
        historyTextArea.setEditable(false);
    }

    @Override
    public void onLoad(EntityBareJid n) {
        roomJid = n;
        this.multiUserChat = loadRoomInfo();
    }

    private MultiUserChat  loadRoomInfo(){

        MultiUserChat multiUserChat = roomClient.loadRoomInfo(this.roomJid);
        try {

            if(!multiUserChat.isJoined()){
                multiUserChat.join(Resourcepart.from(roomClient.getCurrentUser().getLocalpartOrNull().toString()));
            }
            System.out.println(multiUserChat.getOccupants().size());
            System.out.println(multiUserChat.getOccupantsCount());
            List<Affiliate> allList = new ArrayList<>();
            List<Affiliate> ownerList = multiUserChat.getOwners();
            List<Affiliate> adminList =  multiUserChat.getAdmins();
            List<Affiliate> memberList = multiUserChat.getMembers();

            allList.addAll(ownerList);
            allList.addAll(adminList);
            allList.addAll(memberList);

            if(allList == null){
                return multiUserChat;
            }

            for(Affiliate affiliate : allList){
                Label memberLabel = new Label();
                memberLabel.setUserData(affiliate.getJid());
                String name = affiliate.getJid().getLocalpartOrNull().toString();
                String role = affiliate.getAffiliation().name();
                memberLabel.setText(name+"-"+role);
                memerbersVBox.getChildren().add(memberLabel);
            }

        } catch (Exception e) {
            Log.error("获取房间信息出错,roomJid:{}",this.roomJid,e);

        }
        return multiUserChat;
    }


    @FXML
    private void sendRoomMessage(ActionEvent event){
        String text = sendTextArea.getText();
        try {
            //this.multiUserChat.sendMessage(text);
            Chat chat = multiUserChat.createPrivateChat(JidCreate.entityFullFrom("kanghl@firmail.cn/Spark"),null);
            chat.sendMessage(text);
            handlerSendText();
        } catch (Exception e) {
            Log.error("发送消息异常, message body : {}",text,e);
            Alert alert = new Alert(Alert.AlertType.ERROR);
            alert.setContentText("发送消息失败");
            alert.showAndWait();
        }
    }

    @FXML
    private void inviteClicked(ActionEvent event){

        TextInputDialog dialog = new TextInputDialog();
        dialog.setTitle("添加成员");
        dialog.setHeaderText("请输入成员名称");
        Optional<String> result = dialog.showAndWait();
        //如果用户点击了关闭或者取消，取没有数据,直接返回
        if(!result.isPresent()){
            return;
        }
        String username = result.get();
        if(StringUtils.isEmpty(username)){
            return;
        }
        try {
            roomClient.invite(multiUserChat,username);
            return;
        } catch (Exception e) {
            Log.error("发送邀请失败，username:{}",username,e);
        }

        Alert alert = new Alert(Alert.AlertType.ERROR);
        alert.setContentText("发送邀请失败");
        alert.show();

    }

    public void processMessage(String fromJid, String body){
        if(StringUtils.isNullOrEmpty(body)){
            return;
        }
        handlerReceiveText(fromJid, body);
    }

    public synchronized void processPrecense(Jid fromJid,String nickName,String role){
        ObservableList<Node> memberList = memerbersVBox.getChildren();
        for(Node node : memberList){
            Jid bareJid = (Jid)node.getUserData();
            // 如果 jid 相等，则删除原来,并跳出循环
            if(bareJid.getLocalpartOrNull().equals(fromJid.getLocalpartOrNull().toString())){
                memerbersVBox.getChildren().remove(node);
                break;
            }
        }
        // 更新最新的条目
        Label label = new Label();
        label.setUserData(fromJid);
        label.setText(nickName+"-"+role);
        memerbersVBox.getChildren().add(label);
    }

    private void handlerSendText(){
        sendTextArea.clear();
    }

    private void handlerReceiveText(String from,String body){
        String historyText = historyTextArea.getText();
        StringBuilder builder = new StringBuilder(historyText);
        builder.append("\r\n");
        builder.append(from+" : ");
        builder.append(body);
        historyTextArea.setText(builder.toString());
        // 将流动条滚动到最下边
        historyTextArea.setScrollTop(Double.MAX_VALUE);
    }

    public EntityBareJid getRoomJid() {
        return roomJid;
    }

    @Override
    public void register() {
        roomBridge.register(this);
    }

    @Override
    public void unregister() {
        roomBridge.unregister(this);
    }
}
